package edu.neu.swc.commerce.service.impl;

import com.alibaba.fastjson.JSON;
import edu.neu.swc.commerce.account.AddressInfo;
import edu.neu.swc.commerce.common.TableId;
import edu.neu.swc.commerce.filter.AccessContext;
import edu.neu.swc.commerce.vo.LoginUserInfo;
import edu.neu.swc.commerce.dao.EcommerceAddressDao;
import edu.neu.swc.commerce.entity.EcommerceAddress;
import edu.neu.swc.commerce.service.IAddressService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <h1>用户地址相关服务接口实现</h1>
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class AddressServiceImpl implements IAddressService {

    EcommerceAddressDao addressDao;


    public AddressServiceImpl(EcommerceAddressDao ecommerceAddressDao) {
        this.addressDao = ecommerceAddressDao;
    }

    /**
     * <h2>存储多个用户地址信息</h2>
     */
    @Override
    public TableId createAddressInfo(AddressInfo addressInfo) {

        //不能直接拿到用户信息，需要做强校验
        LoginUserInfo loginUserInfo = AccessContext.getLoginUserInfo();

        //将传递的参数转化为实体对象
        List<EcommerceAddress> ecommerceAddresses = addressInfo.getAddressItems()
                .stream()
                .map(a -> EcommerceAddress.to(loginUserInfo.getId(), a))
                .collect(Collectors.toList());

        //保存到数据表，并把返回记录的id给调用方
        List<EcommerceAddress> savedRecords = addressDao.saveAll(ecommerceAddresses);

        List<Long> ids = savedRecords.stream()
                .map(EcommerceAddress::getId)
                .collect(Collectors.toList());

        log.info("create address info:[{}],[{}]",loginUserInfo.getId(),
                JSON.toJSONString(ids));

        return new TableId(ids.stream()
                .map(TableId.Id::new)
                .collect(Collectors.toList()));
    }

    @Override
    public AddressInfo getCurrentAddressInfo() {

        LoginUserInfo loginUserInfo = AccessContext.getLoginUserInfo();

        //根据userId查询到用户地址信息，再实现转换
        List<EcommerceAddress> ecommerceAddresses = addressDao.findAllByUserId(
                loginUserInfo.getId()
        );

        List<AddressInfo.AddressItem> addressItems = ecommerceAddresses.stream()
                .map(EcommerceAddress::toAddressItem)
                .collect(Collectors.toList());
        return new AddressInfo(loginUserInfo.getId(), addressItems);
    }

    @Override
    public AddressInfo getAddressInfoById(Long id) {

        EcommerceAddress ecommerceAddress = addressDao.findById(id).orElse(null);

        if(null == ecommerceAddress){
            throw new RuntimeException("address is not exit");
        }
        return new AddressInfo(
                ecommerceAddress.getUserId(),
                Collections.singletonList(ecommerceAddress.toAddressItem())
        );
    }

    @Override
    public AddressInfo getAddressInfoByTableId(TableId tableId) {
        List<Long> ids = tableId.getIds().stream()
                .map(TableId.Id::getId)
                .collect(Collectors.toList());

        log.info("get address info by table id:[{}]",JSON.toJSONString(ids));

        List<EcommerceAddress> ecommerceAddresses = addressDao.findAllById(ids);

        if(CollectionUtils.isEmpty(ecommerceAddresses)){
            return new AddressInfo(-1L,Collections.emptyList());
        }

        List<AddressInfo.AddressItem> addressItems = ecommerceAddresses.stream()
                .map(EcommerceAddress::toAddressItem)
                .collect(Collectors.toList());
        return new AddressInfo(
                ecommerceAddresses.get(0).getUserId(),
                addressItems
        );
    }
}
